import pandas as pd
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog,\
    QMessageBox,QWidget,QHeaderView,QTableWidgetItem,QAbstractItemView,QStackedLayout,QDateEdit
from PySide6.QtCore import QCoreApplication,QTimer,Qt,QThread,QSize,QDate,Signal
from PySide6.QtGui import QIcon, QPixmap
import sys
sys.path.append("UIProgram")
from UIProgram.MainPro import Ui_MainWindow
from UIProgram.RecWidget import Ui_RecForm
from UIProgram.InfoEntry import Ui_InfoEntryForm
from UIProgram.recRecordWidget import Ui_recRecordFrom
from UIProgram.DataManageWidget import Ui_DataManageForm
from UIProgram.AboutWidget import Ui_aboutForm

from UIProgram.form_one import Ui_Form_one
from UIProgram.form_two import Ui_Form_two
from UIProgram.form_three import Ui_Form_three

import detect_tools as tools
import cv2
import Config
import datetime
import os
from UIProgram.QssLoader import QSSLoader
import warnings
warnings.filterwarnings('ignore')
## 1. 优先配置警告过滤器
warnings.filterwarnings('ignore', category=UserWarning, message='The NumPy module was reloaded')
warnings.filterwarnings('ignore', category=RuntimeWarning)

# 2. 确保只导入一次NumPy
if 'numpy' in sys.modules:
    # 如果NumPy已经被导入，删除它并重新导入
    del sys.modules['numpy']
    import numpy as np
else:
    import numpy as np

# 3. 设置NumPy配置
np.set_printoptions(suppress=True)  # 禁止科学计数法显示
np.seterr(all='ignore')  # 忽略所有NumPy警告

# 4. 设置环境变量
os.environ["QT_LOGGING_RULES"] = "qt*.debug=false;*.warning=false"
os.environ["PYTHONWARNINGS"] = "ignore"  # 全局忽略警告

class RecognitionPage(QWidget, Ui_RecForm):
    def __init__(self):
        super().__init__()
        self.setupUi(self)


class InfoEntryPage(QWidget, Ui_InfoEntryForm):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 设置日期
        current_date = QDate.currentDate()  # 获取当前日期
        self.startdateEdit.setDate(current_date)  # 设置当前日期
        self.startdateEdit.setDisplayFormat("yyyy-MM-dd")  # 设置显示格式
        self.enddateEdit.setDate(current_date)  # 设置当前日期
        self.enddateEdit.setDisplayFormat("yyyy-MM-dd")  # 设置显示格式

class DataManagePage(QWidget, Ui_DataManageForm):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class RecRecordPage(QWidget, Ui_recRecordFrom):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class AboutPage(QWidget, Ui_aboutForm):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class FormOne(QWidget, Ui_Form_one):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class FormTwo(QWidget, Ui_Form_two):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class FormThree(QWidget, Ui_Form_three):
    def __init__(self):
        super().__init__()
        self.setupUi(self)


class MainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.initMain()
        self.signalconnect()
        style_file='UIProgram/style.css'
        qssStyleSheet = QSSLoader.read_qss_file(style_file)
        self.setStyleSheet(qssStyleSheet)
        self.ui.exitBtn.clicked.connect(self.exit_app)

    def signalconnect(self):
        self.recognition_page.PicBtn.clicked.connect(self.rec_open_img)
        self.recognition_page.cameraOpenBtn.clicked.connect(self.rec_camera_show)
        self.recognition_page.cameraCloseBtn.clicked.connect(self.video_stop)
        self.recognition_page.entry_radioButton.clicked.connect(self.change_res_frame)
        self.recognition_page.out_radioButton.clicked.connect(self.change_res_frame)
        # 信息录入界面的信号连接
        self.info_entry_page.PicBtn.clicked.connect(self.info_entry_open_img)
        self.info_entry_page.cameraOpenBtn.clicked.connect(self.info_entry_camera_show)
        self.info_entry_page.cameraCloseBtn.clicked.connect(self.video_stop)

    def change_res_frame(self):
        self.pre_lisence = None
        self.clear_rec_show_info()
        if self.recognition_page.entry_radioButton.isChecked():
            self.recognition_res_qls.setCurrentIndex(2)
        else:
            self.recognition_res_qls.setCurrentIndex(1)

    def rec_camera_show(self):
        self.is_camera_open = True
        self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        self.rec_camera_start()

    def rec_camera_start(self):
        self.rec_time_camera.start(30)
        self.rec_time_camera.timeout.connect(self.rec_open_frame)

        # 更新界面识别信息
        self.rec_info_timer.start(1000)
        self.rec_info_timer.timeout.connect(self.rec_info_update)

    def rec_open_frame(self):
        ret, self.cv_img = self.cap.read()
        if ret:
            image, self.res, self.boxes = tools.info_entry_detect(self.cv_img)
            self.img_width, self.img_height = self.get_resize_size(image)
            resize_cvimg = cv2.resize(image, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
            self.recognition_page.show_label.setPixmap(pix_img)
            self.recognition_page.show_label.setAlignment(Qt.AlignCenter)
        else:
            self.cap.release()
            self.rec_time_camera.stop()

    def info_entry_open_img(self):
        """车辆信息录入界面：打开图片"""
        if self.is_camera_open:
            self.video_stop()

        # 弹出的窗口名称：'打开图片'
        file_path, _ = QFileDialog.getOpenFileName(None, '打开车辆图片', './', "Image files (*.jpg *.jepg *.png)")
        if not file_path:
            return

        # 保存原始图片路径
        self.org_path = file_path

        # 读取图片并显示
        self.cv_img = tools.img_cvread(self.org_path)
        self.img_width, self.img_height = self.get_resize_size(self.cv_img)
        resize_cvimg = cv2.resize(self.cv_img, (self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)

        # 在信息录入界面显示图片
        self.info_entry_page.show_label.setPixmap(pix_img)
        self.info_entry_page.show_label.setAlignment(Qt.AlignCenter)

        # 更新图片路径显示
        self.info_entry_page.PiclineEdit.setText(file_path)

        # 尝试检测车牌
        try:
            # 使用安全的方式调用检测函数
            result = tools.info_entry_detect(self.cv_img.copy())

            # 检查返回结果是否正确
            if not isinstance(result, tuple) or len(result) != 3:
                # 返回结果不符合预期
                print(f"检测函数返回了意外的结果: {result}")
                raise ValueError("检测函数返回无效结果")

            image, res, boxes = result

            # 只有当检测结果有效时才处理
            if boxes is not None and len(boxes) > 0 and res:
                # 显示车牌裁剪区域
                box = boxes[0]
                if not isinstance(box, (tuple, list)):
                    # 确保box是可迭代对象
                    box = (box[0], box[1], box[2], box[3])

                x1, y1, x2, y2 = box
                crop_img = self.cv_img[int(y1):int(y2), int(x1):int(x2)]

                # 调整裁剪图片大小以适应标签
                crop_img = cv2.resize(crop_img, (self.crop_img_width, self.crop_img_height))
                pix_img = tools.cvimg_to_qpiximg(crop_img)
                self.info_entry_page.img_crop_label.setPixmap(pix_img)
                self.info_entry_page.img_crop_label.setAlignment(Qt.AlignCenter)

                # 自动填充车牌号
                self.info_entry_page.lineEdit.setText(res)
            else:
                # 没有检测到车牌
                self.info_entry_page.img_crop_label.clear()
                self.info_entry_page.lineEdit.clear()

        except Exception as e:
            print(f"车牌识别出错: {e}")
            # 出错时清空车牌显示和车牌号
            self.info_entry_page.img_crop_label.clear()
            self.info_entry_page.lineEdit.clear()

    def info_entry_camera_show(self):
        """车辆信息录入界面：开启摄像头"""
        if self.is_camera_open:
            self.video_stop()

        self.is_camera_open = True
        self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        self.info_entry_camera_start()

    def info_entry_camera_start(self):
        """开始更新摄像头画面（信息录入界面）"""
        self.timer_camera.start(30)
        self.timer_camera.timeout.connect(self.info_entry_open_frame)

    def info_entry_open_frame(self):
        """处理信息录入界面的摄像头帧"""
        ret, self.cv_img = self.cap.read()
        if ret:
            # 实时检测车牌
            image, self.res, boxes = tools.info_entry_detect(self.cv_img)

            # 显示摄像头画面
            self.img_width, self.img_height = self.get_resize_size(image)
            resize_cvimg = cv2.resize(image, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
            self.info_entry_page.show_label.setPixmap(pix_img)
            self.info_entry_page.show_label.setAlignment(Qt.AlignCenter)

            # 显示车牌裁剪区域
            if boxes is not None and len(boxes) > 0:
                box = boxes[0]
                x1, y1, x2, y2 = box
                crop_img = self.cv_img[y1:y2, x1:x2]

                # 调整裁剪图片大小
                crop_img = cv2.resize(crop_img, (self.crop_img_width, self.crop_img_height))
                pix_img = tools.cvimg_to_qpiximg(crop_img)
                self.info_entry_page.img_crop_label.setPixmap(pix_img)
                self.info_entry_page.img_crop_label.setAlignment(Qt.AlignCenter)

                # 自动填充车牌号
                self.info_entry_page.lineEdit.setText(self.res)
        else:
            self.video_stop()

    def rec_info_update(self):
        """
        对摄像头识别信息进行界面实时更新，同时将识别记录写入数据库
        :return:
        """
        if not self.res:
            return

        if self.pre_lisence == self.res:
            # 同一车牌，同一时间段，只更新一次界面信息与识别记录信息
            return

        self.pre_lisence = self.res
        # 清空界面显示
        self.clear_rec_show_info()

        # 读取识别记录数据库系数据
        self.recognition_rec_csv_data = tools.read_csv(Config.clock_on_records_file)

        self.is_entry = True if self.recognition_page.entry_radioButton.isChecked() else False

        self.lisence_is_register = self.is_register(self.res)

        now_date_time = datetime.datetime.now().strftime("%Y-%m-%d  %H:%M:%S")
        now_date = datetime.datetime.now().strftime("%Y-%m-%d")
        now_time = datetime.datetime.now().strftime("%H:%M:%S")

        if self.is_entry:
            # 车辆进入时的识别结果
            if self.lisence_is_register[0]:
                self.res_page_three.type_label.setText('登记车辆')
            else:
                self.res_page_three.type_label.setText('外来车辆')
            self.res_page_three.lisence_label.setText(self.res)
            self.res_page_three.entry_time_label.setText(now_time)
            self.res_page_three.total_label.setText(str(Config.total_num))
            # 剩余车位
            remain_num = Config.total_num - tools.get_remaining_num(self.recognition_rec_csv_data)
            self.res_page_three.left_label.setText(str(remain_num))
            self.recognition_res_qls.setCurrentIndex(2)
        else:
            if self.lisence_is_register[0]:
                # 登记车辆，计算剩余天数
                reg_data = self.lisence_is_register[1]
                register_date = reg_data.iloc[0].at['截止日期']
                rest_days = self.get_rest_days(register_date, now_date)

            # 车辆外出识别结果,取最后一条信息
            recognition_res = self.get_entry_out_time(self.res)
            if recognition_res[0] is False:
                # 没查到车辆进出信息
                if self.lisence_is_register[0]:
                    self.res_page_one.lisence_label.setText(self.res)
                    self.res_page_one.type_label.setText('登记车辆')
                    self.res_page_one.day_label.setText(f'{rest_days} 天')
                    self.recognition_res_qls.setCurrentIndex(0)
                else:
                    self.res_page_two.lisence_label.setText(self.res)
                    self.res_page_two.type_label.setText('外来车辆')
                    self.recognition_res_qls.setCurrentIndex(1)
                QMessageBox.about(self, '提示', '未找到该车进入记录！')
                return

            recognition_time = recognition_res[1]
            out_time = recognition_time.iloc[-1].at['外出时间']
            entry_time = recognition_time.iloc[-1].at['进入时间']

            if not (str(out_time) == 'nan' and entry_time):
                # 没查到车辆进出信息
                if self.lisence_is_register[0]:
                    self.res_page_one.lisence_label.setText(self.res)
                    self.res_page_one.type_label.setText('登记车辆')
                    self.res_page_one.day_label.setText(f'{rest_days} 天')
                    self.recognition_res_qls.setCurrentIndex(0)
                else:
                    self.res_page_two.lisence_label.setText(self.res)
                    self.res_page_two.type_label.setText('外来车辆')
                    self.recognition_res_qls.setCurrentIndex(1)
                # 判断是否有该车的进入记录：出去的时间是否为空，且有进入时间
                QMessageBox.about(self, '提示', '未找到该车进入记录！')
                return

            # 计算停车时长:需要查找进入时间
            stop_hours = self.get_stop_hours(entry_time, now_date_time)

            # 费用计算:不足半小时免费，超过每小时5元，不足1小时按1小时算,每24小时20元封顶
            if stop_hours[0] == 0 and stop_hours[1] <= 30:
                money = 0
            else:
                # 小时stop_hours[0]  分钟stop_hours[1]
                days = int(stop_hours[0] / 24)
                hours = stop_hours[0] + (1 if stop_hours[1] > 0 else 0) - days * 24
                money = days * 20 + min(20, hours * 5)

            if self.lisence_is_register[0]:
                # 计算剩余天数
                reg_data = self.lisence_is_register[1]
                register_date = reg_data.iloc[0].at['截止日期']
                rest_days = self.get_rest_days(register_date, now_date)
                self.res_page_one.lisence_label.setText(self.res)
                self.res_page_one.type_label.setText('登记车辆')
                self.res_page_one.day_label.setText(f'{rest_days} 天')
                self.res_page_one.hour_label.setText(f'{stop_hours[0]}小时{stop_hours[1]}分')
                if rest_days > 0:
                    # 登记剩余天数大于0，不收费
                    self.res_page_one.money_lb.setText('0 元')
                else:
                    self.res_page_one.money_lb.setText(f'{money} 元')
                self.recognition_res_qls.setCurrentIndex(0)
            else:
                self.res_page_two.lisence_label.setText(self.res)
                self.res_page_two.type_label.setText('外来车辆')
                self.res_page_two.hour_label.setText(f'{stop_hours[0]}小时{stop_hours[1]}分')
                self.res_page_two.money_lb.setText(f'{money} 元')
                self.recognition_res_qls.setCurrentIndex(1)

        # # 更新车牌识别打卡数据
        rec_time = datetime.datetime.now().strftime("%Y-%m-%d  %H:%M:%S")
        type_txt = '登记车辆' if self.lisence_is_register[0] else '外来车辆'
        if self.is_entry:
            line_data = [self.res, rec_time, '', type_txt]
        else:
            line_data = [self.res, '', rec_time, type_txt]
        tools.insert_rows(Config.clock_on_records_file, [line_data], self.recognition_info_csv_header)


    def initMain(self):
        self.data_path=Config.data_path

        self.show_width=500
        self.show_height=300

        self.crop_img_width=340
        self.crop_img_height=190

        self.is_camera_open=False

        self.cap=None

        #车辆进出模拟标志
        self.is_entry=True

        #车牌识别结果
        self.res=None

        #用于控制摄像头识别时，进出车辆显示信息的更新，每次进入与出来只更新一次信息
        self.pre_lisence=None

        # 默认是外来车辆
        self.lisence_is_register = False

        # 车辆图片
        self.org_photo_img = None

        self.data_info_csv_header = ['序号', '车辆牌照', '照片路径', '登记日期', '截止日期', '业主姓名', '业主电话',
                                     '业主地址', '修改时间']
        self.recognition_info_csv_header = ['序号', '车辆牌照', '进入时间', '外出时间', '车辆类型']
        # 数据文件创建
        # 如果不存在文件，则创建文件
        if not os.path.exists(self.data_path):
            tools.creat_csv(self.data_path, self.data_info_csv_header)
        # 读取数据库信息
        self.database_data = tools.read_csv(self.data_path)

        if not os.path.exists(Config.clock_on_records_file):
            tools.creat_csv(Config.clock_on_records_file, self.recognition_info_csv_header)

        self.timeshow_timer = QTimer()

        # 更新视频图像
        self.timer_camera = QTimer()
        self.rec_time_camera = QTimer()

        # 更新车牌识别的结果信息
        self.rec_info_timer = QTimer()

        self.recognition_page = RecognitionPage()
        self.info_entry_page = InfoEntryPage()
        self.data_manage_page = DataManagePage()
        self.rec_record_page = RecRecordPage()
        self.about_page = AboutPage()

        self.qls = QStackedLayout(self.ui.show_frame)
        self.qls.addWidget(self.recognition_page)
        self.qls.addWidget(self.info_entry_page)
        self.qls.addWidget(self.data_manage_page)
        self.qls.addWidget(self.rec_record_page)
        self.qls.addWidget(self.about_page)

        self.ui.RecBtn.clicked.connect(self.buttonIsClicked)
        self.ui.infoEntryBtn.clicked.connect(self.buttonIsClicked)
        self.ui.dataManageBtn.clicked.connect(self.buttonIsClicked)
        self.ui.recRecordBtn.clicked.connect(self.buttonIsClicked)
        self.qls.setCurrentIndex(1)

        # 改变颜色
        self.ui.RecBtn.clicked.connect(self.btn_click)
        self.ui.infoEntryBtn.clicked.connect(self.btn_click)
        self.ui.dataManageBtn.clicked.connect(self.btn_click)
        self.ui.recRecordBtn.clicked.connect(self.btn_click)

        self.ui.infoEntryBtn.setStyleSheet("background-color: lawngreen")
        self.ui.RecBtn.setStyleSheet("background-color: lightgray")
        self.ui.dataManageBtn.setStyleSheet("background-color: lightgray")
        self.ui.recRecordBtn.setStyleSheet("background-color: lightgray")
        self.ui.exitBtn.setStyleSheet("background-color: lightgray")

        # 显示时间
        now_time = datetime.datetime.now().strftime("%H:%M:%S")
        print('now_time: ', now_time, 'type: ', type(now_time))
        self.ui.lcdNumber.setDigitCount(8)  # 设置显示位数
        self.ui.lcdNumber.display(now_time)

        self.timeshow_timer.start(1000)
        self.timeshow_timer.timeout.connect(self.time_show_fun)

        # 识别结果界面切换
        self.res_page_one = FormOne()
        self.res_page_two = FormTwo()
        self.res_page_three = FormThree()

        self.recognition_res_qls = QStackedLayout(self.recognition_page.res_frame)
        self.recognition_res_qls.addWidget(self.res_page_one)
        self.recognition_res_qls.addWidget(self.res_page_two)
        self.recognition_res_qls.addWidget(self.res_page_three)
        self.recognition_res_qls.setCurrentIndex(2)

        # 打卡信息表格设置
        self.rec_record_page.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.rec_record_page.tableWidget.verticalHeader().setDefaultSectionSize(60)  # 设定行高
        self.rec_record_page.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 表格铺满
        self.rec_record_page.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
        self.rec_record_page.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 设置表格不可编辑
        self.rec_record_page.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置表格整行选中
        self.rec_record_page.tableWidget.verticalHeader().setVisible(False)  # 隐藏列标题
        self.rec_record_page.tableWidget.setAlternatingRowColors(True)  # 表格背景交替

        # 数据管理表格设置
        # 设置固定行高为120
        self.data_manage_page.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.data_manage_page.tableWidget.verticalHeader().setDefaultSectionSize(100)
        self.data_manage_page.tableWidget.setColumnWidth(3, 150)  # 设置列宽
        self.data_manage_page.tableWidget.setColumnWidth(4, 150)
        # self.data_manage_page.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 表格铺满
        # self.data_manage_page.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
        # self.data_manage_page.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 设置表格不可编辑
        self.data_manage_page.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置表格整行选中
        self.data_manage_page.tableWidget.verticalHeader().setVisible(False)  # 隐藏列标题
        self.data_manage_page.tableWidget.setAlternatingRowColors(True)  # 表格背景交替

        self.clear_rec_show_info()  # 清空结果显示信息
        # 设置主页背景图片border-image: url(:/icons/ui_imgs/icons/camera.png)
        self.setObjectName("MainWindow")
        # self.setStyleSheet(f"#MainWindow{{background-image:url({Config.mainwin_bg_img})}}")
        # self.setStyleSheet(f"#MainWindow{{border-image:url({Config.mainwin_bg_img})}}")

        self.cam = cv2.VideoCapture(0)
        # 信息录入界面默认值设置
        self.info_entry_page.lineEdit_2.setText("张三")  # 默认业主姓名
        self.info_entry_page.lineEdit_3.setText("13800138000")  # 默认联系电话
        self.info_entry_page.lineEdit_4.setText("北京市朝阳区")  # 默认地址



    def time_show_fun(self):
        now_time = datetime.datetime.now().strftime("%H:%M:%S")
        self.ui.lcdNumber.display(now_time)

    # 在 MainWindow 类中添加以下方法
    def Records_tabel_info_show(self, pd_data):
        """
        显示识别记录的数据库信息
        :param pd_data: pandas DataFrame 数据
        """
        # 清空表格所有行
        self.rec_record_page.tableWidget.setRowCount(0)
        self.rec_record_page.tableWidget.clearContents()  # 清空表格内容，不含表头

        # 设置表格列数（根据表头自动获取）
        header_labels = list(pd_data.columns)
        self.rec_record_page.tableWidget.setColumnCount(len(header_labels))
        self.rec_record_page.tableWidget.setHorizontalHeaderLabels(header_labels)

        # 填充数据
        for index, row in pd_data.iterrows():
            row_count = self.rec_record_page.tableWidget.rowCount()
            self.rec_record_page.tableWidget.insertRow(row_count)

            # 为每列创建表格项
            for col_idx, col_name in enumerate(header_labels):
                value = str(row[col_name]) if pd.notna(row[col_name]) else ""  # 处理NaN值
                item = QTableWidgetItem(value)
                item.setTextAlignment(Qt.AlignCenter)  # 居中对齐

                # 序号列设置为只读
                if col_name == "序号":
                    item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 不可编辑

                self.rec_record_page.tableWidget.setItem(row_count, col_idx, item)

        # 设置自动调整列宽
        self.rec_record_page.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.rec_record_page.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)  # 序号列可手动调整

    def buttonIsClicked(self):
        sender = self.sender().objectName()
        dic = {
            "RecBtn": 0,
            "infoEntryBtn": 1,
            "dataManageBtn": 2,
            "recRecordBtn": 3,
        }
        index = dic[sender]
        print("当前的按钮为：", index)

        self.qls.setCurrentIndex(index)

        self.clear_rec_show_info()
        self.recognition_page.PiclineEdit.clear()
        self.recognition_page.show_label.clear()
        # #
        #
        self.clear_entry_show_info()
        self.info_entry_page.PiclineEdit.clear()
        self.info_entry_page.show_label.clear()
        #
        if index == 0:
            self.pre_lisence = None

        if index == 1:
            self.org_photo_img = None

        if index in [0, 1, 2]:
            # 需重新读取数据库
            self.database_data = tools.read_csv(self.data_path)
        #
        if index == 2:
            self.data_tabel_info_show(self.database_data)

        if index in [0, 3]:
            # 识别界面与识别信息管理界面需要读取，识别记录信息数据库
            path = Config.clock_on_records_file
            # 如果不存在文件，则创建文件
            if not os.path.exists(path):
                tools.creat_csv(path, self.recognition_info_csv_header)

            self.recognition_rec_csv_data = tools.read_csv(path)

            # 修改 buttonIsClicked 方法中的这一部分
            if index == 3:
                # 读取识别记录CSV文件
                path = Config.clock_on_records_file
                if not os.path.exists(path):
                    tools.creat_csv(path, self.recognition_info_csv_header)

                self.recognition_rec_csv_data = tools.read_csv(path)
                self.Records_tabel_info_show(self.recognition_rec_csv_data)  # 调用新方法显示数据

        if self.is_camera_open is True:
            self.video_stop()

    # 添加退出应用的方法
    def exit_app(self):
        # 先关闭摄像头
        self.video_stop()

        # 改变退出按钮颜色
        self.btn_click_exit()

        # 显示退出确认对话框
        reply = QMessageBox.question(self, '退出确认',
                                         '确定要退出停车场管理系统吗？',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)

        if reply == QMessageBox.Yes:
            # 退出应用
            QCoreApplication.quit()
        else:
            # 取消退出，恢复按钮颜色
            self.btn_click()

    # 添加退出按钮点击时的特殊处理
    def btn_click_exit(self):
        """
        退出按钮的点击特殊处理 - 只改变退出按钮颜色
        """
        btns = [self.ui.RecBtn, self.ui.infoEntryBtn, self.ui.dataManageBtn, self.ui.recRecordBtn, self.ui.exitBtn]
        for btn in btns:
            if btn == self.ui.exitBtn:
                btn.setStyleSheet("background-color: lawngreen")
            else:
                btn.setStyleSheet("background-color: lightgray")

    def btn_click(self):
        """
        将激活的按钮颜色变为绿色
        :return:
        """
        sender = self.sender()
        # 排除退出按钮处理（退出按钮有单独的处理）
        if sender == self.ui.exitBtn:
            return

        btns = [self.ui.RecBtn, self.ui.infoEntryBtn, self.ui.dataManageBtn, self.ui.recRecordBtn, self.ui.exitBtn]
        for btn in btns:
            if btn == sender:
                btn.setStyleSheet("background-color: lawngreen")
            else:
                # 不要改变退出按钮的颜色
                if btn != self.ui.exitBtn:
                    btn.setStyleSheet("background-color: lightgray")

    def clear_rec_show_info(self):
        """
        清除识别界面的详细信息
        :return:
        """
        self.res_page_one.lisence_label.clear()
        self.res_page_one.type_label.clear()
        self.res_page_one.day_label.clear()
        self.res_page_one.hour_label.clear()
        self.res_page_one.money_lb.clear()

        self.res_page_two.lisence_label.clear()
        self.res_page_two.type_label.clear()
        self.res_page_two.hour_label.clear()
        self.res_page_two.money_lb.clear()

        self.res_page_one.lisence_label.clear()
        self.res_page_one.type_label.clear()
        self.res_page_one.day_label.clear()
        self.res_page_one.hour_label.clear()
        self.res_page_one.money_lb.clear()

        self.res_page_three.lisence_label.clear()
        self.res_page_three.type_label.clear()
        self.res_page_three.entry_time_label.clear()
        self.res_page_three.total_label.clear()
        self.res_page_three.left_label.clear()


    def clear_entry_show_info(self):
        """
        清除录入界面的详细信息
        :return:
        """
        self.info_entry_page.lineEdit.setText('')
        self.info_entry_page.lineEdit_2.setText('')
        self.info_entry_page.lineEdit_3.setText('')
        self.info_entry_page.lineEdit_4.setText('')
        self.info_entry_page.img_crop_label.clear()

    def data_tabel_info_show(self, pd_data):
        """
        显示登记的数据库信息
        :param csv_data:
        :return:
        """
        # 清空表格所有行
        self.data_manage_page.tableWidget.setRowCount(0)
        self.data_manage_page.tableWidget.clearContents()  # 清空表格内容，不含表头

        self.data_manage_page.tableWidget.setIconSize(QSize(120, 120))  # 设置图片大小
        for index, row in pd_data.iterrows():
            row_count = self.data_manage_page.tableWidget.rowCount()  # 返回当前行数(尾部)
            self.data_manage_page.tableWidget.insertRow(row_count)  # 尾部插入一行

            item_id = QTableWidgetItem(str(row['序号']))  # 序号
            item_id.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            item_id.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            item_lisence = QTableWidgetItem(row['车辆牌照'])
            item_lisence.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            item_lisence.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            item_pic = QTableWidgetItem()
            icon = QIcon(row['照片路径'])
            item_pic.setIcon(QIcon(icon))
            item_pic.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            item_pic.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            # item_startdate = QTableWidgetItem()
            start_date = row['登记日期']
            start_dateEdit = QDateEdit()
            dates = start_date.split('-')
            d = QDate(int(dates[0]), int(dates[1]), int(dates[2]))
            start_dateEdit.setDate(d)
            start_dateEdit.setCalendarPopup(True)
            start_dateEdit.setDisplayFormat("yyyy-MM-dd")
            # self.data_manage_page.tablewidget.setCellWidget(0, 1, start_dateEdit)

            end_date = row['截止日期']
            end_dateEdit = QDateEdit()
            dates = end_date.split('-')
            d = QDate(int(dates[0]), int(dates[1]), int(dates[2]))
            end_dateEdit.setDate(d)
            end_dateEdit.setCalendarPopup(True)
            end_dateEdit.setDisplayFormat("yyyy-MM-dd")
            # self.data_manage_page.tablewidget.setCellWidget(0, 1, start_dateEdit)

            item_name = QTableWidgetItem(str(row['业主姓名']))
            item_name.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            # item_name.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑
            item_phonenum = QTableWidgetItem(str(row['业主电话']))
            item_phonenum.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            # item_phonenum.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            item_address = QTableWidgetItem(str(row['业主地址']))
            item_address.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            # item_address.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            item_save_time = QTableWidgetItem(str(row['修改时间']))
            item_save_time.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            item_save_time.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置不可编辑

            self.data_manage_page.tableWidget.setItem(row_count, 0, item_id)
            self.data_manage_page.tableWidget.setItem(row_count, 1, item_lisence)
            self.data_manage_page.tableWidget.setItem(row_count, 2, item_pic)
            self.data_manage_page.tableWidget.setCellWidget(row_count, 3, start_dateEdit)
            self.data_manage_page.tableWidget.setCellWidget(row_count, 4, end_dateEdit)
            self.data_manage_page.tableWidget.setItem(row_count, 5, item_name)
            self.data_manage_page.tableWidget.setItem(row_count, 6, item_phonenum)
            self.data_manage_page.tableWidget.setItem(row_count, 7, item_address)
            self.data_manage_page.tableWidget.setItem(row_count, 8, item_save_time)

    def video_stop(self):
        """
        关闭摄像头或者视频
        :return:
        """
        self.is_camera_open = False
        if self.cap is not None:
            self.cap.release()
        self.timer_camera.stop()
        self.rec_time_camera.stop()
        self.rec_info_timer.stop()

        # 清空所有界面的显示
        self.recognition_page.show_label.clear()

        # 重置信息录入界面的显示
        no_camera_pixmap = QPixmap("UIProgram/ui_imgs/icons/camera.png") \
            .scaled(self.show_width, self.show_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.info_entry_page.show_label.setPixmap(no_camera_pixmap)
        self.info_entry_page.show_label.setAlignment(Qt.AlignCenter)

        no_lisence_pixmap = QPixmap("UIProgram/ui_imgs/icons/车牌识别.png") \
            .scaled(self.crop_img_width, self.crop_img_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.info_entry_page.img_crop_label.setPixmap(no_lisence_pixmap)
        self.info_entry_page.img_crop_label.setAlignment(Qt.AlignCenter)

        self.clear_rec_show_info()

    def is_register(self, name):
        """
        判断车辆是否是已登记的车辆,并获取登记信息
        :param name: 车牌号
        :return:
        """
        data_list = self.database_data.loc[self.database_data['车辆牌照'].str.contains(str(name))]
        if len(data_list) >= 1:
            return True, data_list
        else:
            return False, None

    def get_resize_size(self, img):
        _img = img.copy()
        img_height, img_width, depth = _img.shape
        ratio = img_width / img_height
        if ratio >= self.show_width / self.show_height:
            self.img_width = self.show_width
            self.img_height = int(self.img_width / ratio)
        else:
            self.img_height = self.show_height
            self.img_width = int(self.img_height * ratio)
        return self.img_width, self.img_height

    def get_rest_days(self, out_time, entry_time):
        """
        计算已登记车辆的剩余天数
        给定两个时间字符串，格式2023-4-3，返回天数
        :param entry_time: 车辆进入时间
        :param out_time: 车辆过期日期
        :return:
        """
        st_time = datetime.datetime.strptime(entry_time, "%Y-%m-%d")
        end_time = datetime.datetime.strptime(out_time, "%Y-%m-%d")
        delta_time = end_time - st_time
        days = delta_time.days
        if days <= 0:
            days = 0
        return days

    def get_entry_out_time(self, lisense):
        """
        查找车辆的进入时间与出去的时间
        :param lisense:
        :return:
        """
        pd_data = self.recognition_rec_csv_data.loc[
            self.recognition_rec_csv_data['车辆牌照'].str.contains(str(lisense))]
        if len(pd_data) >= 1:
            return True, pd_data
        else:
            return False, None

    def get_stop_hours(self, entry_time, out_time):
        """
        给定两个时间字符串，格式2023-4-3 12:30:30，返回时间差：小时与分种
        :param entry_time:
        :param out_time:
        :return:
        """
        st_time = datetime.datetime.strptime(entry_time, "%Y-%m-%d %H:%M:%S")
        end_time = datetime.datetime.strptime(out_time, "%Y-%m-%d %H:%M:%S")
        delta_time = end_time - st_time
        all_seconds = delta_time.total_seconds()
        float_hours = all_seconds / 3600
        int_hour = int(float_hours)
        minutes = int((float_hours - int_hour) * 60)

        return int_hour, minutes

    def rec_open_img(self):
        if self.is_camera_open is True:
            # 关闭摄像头
            self.video_stop()
        # 读取识别记录数据库系数据
        self.recognition_rec_csv_data = tools.read_csv(Config.clock_on_records_file)
        self.clear_rec_show_info()
        # 弹出的窗口名称：'打开图片'
        # 默认打开的目录：'./'
        # 只能打开.jpg与.gif结尾的图片文件
        # file_path, _ = QFileDialog.getOpenFileName(self.ui.centralwidget, '打开图片', './', "Image files (*.jpg *.gif)")
        file_path, _ = QFileDialog.getOpenFileName(None, '打开图片', './', "Image files (*.jpg *.jepg *.png)")
        if not file_path:
            return

        self.org_path = file_path
        self.cv_img = tools.img_cvread(self.org_path)
        self.org_photo_img = self.cv_img.copy()
        image, res, boxes = tools.info_entry_detect(self.org_photo_img)

        if boxes is None:
            self.img_width, self.img_height = self.get_resize_size(image)
            resize_cvimg = cv2.resize(image, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
            self.recognition_page.show_label.setPixmap(pix_img)
            self.recognition_page.show_label.setAlignment(Qt.AlignCenter)

            # 设置路径显示
            self.recognition_page.PiclineEdit.setText(file_path)
            QMessageBox.about(self, '提示', '未识别到车牌，请重新选择图片！')
            return

        self.img_width, self.img_height = self.get_resize_size(image)
        resize_cvimg = cv2.resize(image, (self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
        self.recognition_page.show_label.setPixmap(pix_img)
        self.recognition_page.show_label.setAlignment(Qt.AlignCenter)

        # 设置路径显示
        self.recognition_page.PiclineEdit.setText(file_path)

        self.is_entry = True if self.recognition_page.entry_radioButton.isChecked() else False
        self.lisence_is_register = self.is_register(res)

        now_date_time = datetime.datetime.now().strftime("%Y-%m-%d  %H:%M:%S")
        now_date = datetime.datetime.now().strftime("%Y-%m-%d")
        now_time = datetime.datetime.now().strftime("%H:%M:%S")

        if self.is_entry:
            # 车辆进入时的识别结果
            if self.lisence_is_register[0]:
                self.res_page_three.type_label.setText('登记车辆')
            else:
                self.res_page_three.type_label.setText('外来车辆')
            self.res_page_three.lisence_label.setText(res)
            self.res_page_three.entry_time_label.setText(now_time)
            self.res_page_three.total_label.setText(str(Config.total_num))
            # 剩余车位
            remain_num = Config.total_num - tools.get_remaining_num(self.recognition_rec_csv_data)
            self.res_page_three.left_label.setText(str(remain_num))

            self.recognition_res_qls.setCurrentIndex(2)
        else:
            if self.lisence_is_register[0]:
                # 登记车辆，计算剩余天数
                reg_data = self.lisence_is_register[1]
                register_date = reg_data.iloc[0].at['截止日期']
                rest_days = self.get_rest_days(register_date, now_date)

            # 车辆外出识别结果,取最后一条信息
            recognition_res = self.get_entry_out_time(res)
            if recognition_res[0] is False:
                if self.lisence_is_register[0]:
                    self.res_page_one.lisence_label.setText(res)
                    self.res_page_one.type_label.setText('登记车辆')
                    self.res_page_one.day_label.setText(f'{rest_days} 天')
                    self.recognition_res_qls.setCurrentIndex(0)
                else:
                    self.res_page_two.lisence_label.setText(res)
                    self.res_page_two.type_label.setText('外来车辆')
                    self.recognition_res_qls.setCurrentIndex(1)
                QMessageBox.about(self, '提示', '未找到该车进入记录！')
                return

            recognition_time = recognition_res[1]
            out_time = recognition_time.iloc[-1].at['外出时间']
            entry_time = recognition_time.iloc[-1].at['进入时间']

            if not (str(out_time) == 'nan' and entry_time):
                # 查看数据是否是进入时记录的数据：outtime为nan, 且有进入时间
                if self.lisence_is_register[0]:
                    self.res_page_one.lisence_label.setText(res)
                    self.res_page_one.type_label.setText('登记车辆')
                    self.res_page_one.day_label.setText(f'{rest_days} 天')
                    self.recognition_res_qls.setCurrentIndex(0)
                    self.res_page_two.type_label.setText('登记车辆')
                else:
                    self.res_page_two.lisence_label.setText(res)
                    self.res_page_two.type_label.setText('外来车辆')
                    self.recognition_res_qls.setCurrentIndex(1)

                # 判断是否有该车的进入记录：出去的时间是否为空，且有进入时间
                QMessageBox.about(self, '提示', '未找到该车进入记录！')
                return

            # 计算停车时长:需要查找进入时间
            stop_hours = self.get_stop_hours(entry_time, now_date_time)

            # 费用计算:不足半小时免费，超过每小时5元，不足1小时按1小时算,每24小时20元封顶
            if stop_hours[0] == 0 and stop_hours[1] <= 30:
                money = 0
            else:
                # 小时stop_hours[0]  分钟stop_hours[1]
                days = int(stop_hours[0] / 24)
                hours = stop_hours[0] + (1 if stop_hours[1] > 0 else 0) - days * 24
                money = days * 20 + min(20, hours * 5)

            if self.lisence_is_register[0]:
                self.res_page_one.lisence_label.setText(res)
                self.res_page_one.type_label.setText('登记车辆')
                self.res_page_one.day_label.setText(f'{rest_days} 天')
                self.res_page_one.hour_label.setText(f'{stop_hours[0]}小时{stop_hours[1]}分')

                if rest_days > 0:
                    # 登记剩余天数大于0，不收费
                    self.res_page_one.money_lb.setText('0 元')
                else:
                    self.res_page_one.money_lb.setText(f'{money} 元')
                self.recognition_res_qls.setCurrentIndex(0)
            else:
                self.res_page_two.lisence_label.setText(res)
                self.res_page_two.type_label.setText('外来车辆')
                self.res_page_two.hour_label.setText(f'{stop_hours[0]}小时{stop_hours[1]}分')
                self.res_page_two.money_lb.setText(f'{money} 元')
                self.recognition_res_qls.setCurrentIndex(1)

        # # 更新车牌识别打卡数据
        rec_time = datetime.datetime.now().strftime("%Y-%m-%d  %H:%M:%S")
        type_txt = '登记车辆' if self.lisence_is_register[0] else '外来车辆'

        if self.is_entry:
            line_data = [res, rec_time, '', type_txt]
        else:
            line_data = [res, '', rec_time, type_txt]
        tools.insert_rows(Config.clock_on_records_file, [line_data], self.recognition_info_csv_header)


if __name__ == '__main__':
    # 初始化
    app = QApplication(sys.argv)
    win=MainWindow()
    win.show()
    sys.exit(app.exec())




